package com.naiterui.ehp.bs.emr.utils.his;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.naiterui.ehp.bp.support.exception.BaseExceptionCodes;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.utils.lang.ConfigUtil;
import com.naiterui.ehp.bp.utils.net.RestHttpUtil;
import com.naiterui.ehp.bs.emr.utils.his.param.AesUtils;
import com.naiterui.ehp.bs.emr.utils.his.param.Request;
import com.naiterui.ehp.bs.emr.utils.his.param.Response;
import com.naiterui.ehp.bs.emr.utils.his.param.resp.AnalyzeResp;
import com.naiterui.ehp.bs.emr.utils.his.param.resp.CaseResp;
import com.naiterui.ehp.bs.emr.utils.his.param.resp.ExamineResp;
import com.naiterui.ehp.bs.emr.utils.his.param.resp.MedicalResp;
import com.naiterui.ehp.bs.emr.utils.his.param.resp.PrescriptionItem;
import com.naiterui.ehp.bs.emr.utils.his.param.resp.PrescriptionResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author yiren
 * @since 2022/1/24
 */
@Slf4j
public class HisApi {
    private static final String HIS_URL = ConfigUtil.getString("his.api.offline.url");
    private static final String HIS_KEY = ConfigUtil.getString("his.api.offline.key");
    // 查询病人信息
    private static final String MSGNO_INQUIRER_GET = "1208";
    // 获取门诊病历信息
    private static final String MSGNO_CASE_GET = "1205";
    // 获取处方记录
    private static final String MSGNO_PRESCRIPTION_GET = "1206";
    // 获取化验记录
    private static final String MSGNO_ANALYZE_GET = "1201";
    // 获取检查记录
    private static final String MSGNO_EXAMINE_GET = "1209";


    /**
     * 获取就诊人
     *
     * @param name
     * @param idCard
     * @return
     * @throws BusinessException
     */
    public static List<MedicalResp> getMedical(String idCard, String name) throws BusinessException {
        JSONObject input = new JSONObject();
        input.putOnce("xm", name);
        input.putOnce("sfzh", idCard);
        String json = sendPost(MSGNO_INQUIRER_GET, input);
        JSONObject jsonObject = JSONUtil.parseObj(json);
        if (jsonObject == null || jsonObject.getInt("flag") != 0) {
            throw new BusinessException(BaseExceptionCodes.FAILED, "未找到就诊人信息");
        }
        JSONArray jsonArray = jsonObject.getJSONArray("reginfo");
        List<MedicalResp> resultList = new ArrayList<>();
        jsonArray.jsonIter().forEach(item -> {
            String mzh = item.getStr("outpat_no");
            try {
                CaseResp caseResp = getCase(mzh);
                MedicalResp resp = new MedicalResp();
                resp.setMzh(mzh);
                resp.setInquirerName(caseResp.getInquirerName());
                resp.setVistingTime(caseResp.getVistingTime());
                resp.setDiagnosis(caseResp.getDiagnosis());
                resp.setDoctorName(caseResp.getDoctorName());
                resp.setDepartmentName(caseResp.getDepartmentName());
                resultList.add(resp);
            } catch (BusinessException e) {
                log.error("查询病历信息异常mzh: {}", mzh, e);
            }
        });
        return resultList;
    }


    /**
     * 查询病历信息
     *
     * @param mzh
     * @return
     * @throws BusinessException
     */
    public static CaseResp getCase(String mzh) throws BusinessException {
        JSONObject input = new JSONObject();
        input.putOnce("mzh", mzh);
        String json = sendPost(MSGNO_CASE_GET, input);
        JSONObject jsonObject = JSONUtil.parseObj(json);
        return CaseResp.of(jsonObject);
    }

    /**
     * 查询处方记录
     *
     * @param mzh
     * @return
     * @throws BusinessException
     */
    public static List<PrescriptionResp> getPrescription(String mzh) throws BusinessException {
        JSONObject input = new JSONObject();
        input.putOnce("mzh", mzh);
        String jsonStr = sendPost(MSGNO_PRESCRIPTION_GET, input);
        JSONArray jsonArray = JSONUtil.parseArray(jsonStr);
        List<PrescriptionResp> result = new ArrayList<>();
        Map<String, PrescriptionResp> tempMap = new HashMap<>();
        jsonArray.jsonIter().forEach(json -> {
            String serialNumber = json.getStr("cfid");
            PrescriptionResp resp = tempMap.get(serialNumber);
            if (resp == null) {
                resp = PrescriptionResp.builder()
                        .serialNumber(serialNumber)
                        .diagnosis(json.getStr("zd"))
                        .items(new ArrayList<>())
                        .build();
                result.add(resp);
                tempMap.put(serialNumber, resp);
            }
            PrescriptionItem item = new PrescriptionItem();
            item.setName(json.getStr("ypmc").trim() + " " + json.getStr("gg") + "/" + json.getStr("pack_unit"));
            item.setQuantity(json.getInt("pack_value"));
            item.setUsages(json.getStr("pc") + "，每次" + json.getStr("yl") + "，" + json.getStr("tj") + "，周期：" + json.getStr("ts") + "天");
            resp.getItems().add(item);
        });
        return result;
    }

    /**
     * 查询化验记录
     *
     * @param mzh
     * @return
     * @throws BusinessException
     */
    public static List<AnalyzeResp> getAnalyze(String mzh) throws BusinessException {
        JSONObject input = new JSONObject();
        input.putOnce("mzh", mzh);
        String jsonStr = sendPost(MSGNO_ANALYZE_GET, input);
        JSONArray jsonArray = JSONUtil.parseArray(jsonStr);
        List<AnalyzeResp> resultList = new ArrayList<>();
        jsonArray.jsonIter().forEach(json -> resultList.add(AnalyzeResp.of(json)));
        return resultList;
    }

    /**
     * 查询检查记录
     *
     * @param mzh
     * @return
     * @throws BusinessException
     */
    public static List<ExamineResp> getExamine(String mzh) throws BusinessException {
        JSONObject input = new JSONObject();
        input.putOnce("mzh", mzh);
        String jsonStr = sendPost(MSGNO_EXAMINE_GET, input);
        JSONArray jsonArray = JSONUtil.parseArray(jsonStr);
        List<ExamineResp> resultList = new ArrayList<>();
        jsonArray.jsonIter().forEach(json -> resultList.add(ExamineResp.of(json)));
        return resultList;
    }

    private static String sendPost(String msgno, JSONObject input) throws BusinessException {
        String aesInput = AesUtils.encrypt(input.toString(), HIS_KEY);
        Request request = Request.builder().msgno(msgno).inputparam(aesInput).build();
        ResponseEntity<Response> responseEntity = RestHttpUtil.post().url(HIS_URL).body(JSONUtil.toJsonStr(request))
                .execute(new ParameterizedTypeReference<Response>() {
                });
        if (!HttpStatus.Series.valueOf(responseEntity.getStatusCodeValue()).equals(HttpStatus.Series.SUCCESSFUL)) {
            throw new BusinessException(BaseExceptionCodes.HTTP_ERROR);
        }
        Response response = responseEntity.getBody();
        if (!"0".equals(response.getStatus())) {
            throw new BusinessException(BaseExceptionCodes.FAILED, response.getErrmsg());
        }
        String output = response.getOutput();
        try {
            String json = AesUtils.decrypt(output, HIS_KEY);
            log.info("【{}】请求结果：{}", msgno, json);
            return json;
        } catch (Exception e) {
            log.error("请求结果解密失败，output: {}", output);
            throw new BusinessException(BaseExceptionCodes.FAILED, "请求结果解密失败");
        }
    }
}
